package user

import (
	"bytes"
	"chaowan/data_source"
	"chaowan/models"
	"encoding/json"
	"fmt"
	"github.com/DanPlayer/randomname"
	"github.com/gin-gonic/gin"
	"github.com/xlstudio/wxbizdatacrypt"
	"io/ioutil"
	"net/http"
	"time"
)

const (
	code2sessionURL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
	appID           = "wxefb45719a26251de"
	appSecret       = "6bde284e7ea3a0f723bcfe381cd73b9d"
)

type KDRespBody struct {
	Code    string `json:"code" from:"code"`
	Uid     int64  `json:"uid" from:"uid"`
	Qudao   string `json:"qudao"`
	ClickId string `json:"click_id" gorm:"click_id"`
}

func Xcxopenid(ctx *gin.Context) {
	json1 := KDRespBody{}
	ctx.ShouldBind(&json1)
	wxMap, err := sendWxAuthAPI(json1.Code)
	uid := json1.Uid
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "服务出错",
		})
		return
	}
	if _, ok := wxMap["errcode"]; ok {
		fmt.Println(wxMap["errmsg"])
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "请重新登录",
		})
		return
	}
	routine_openid := wxMap["openid"].(string)
	unionid := wxMap["unionid"].(string)
	session_key := wxMap["session_key"].(string)
	reqip := ctx.ClientIP()
	var user models.User
	data_source.Db.Where("id = ?", uid).First(&user)
	upuser1 := models.User{
		LoginIp:       reqip,
		LoginTime:     time.Now().Unix(),
		LoginNum:      user.LoginNum + 1,
		Newuser:       2,
		SessionKey:    session_key,
		RoutineOpenid: routine_openid,
		Unionid:       unionid,
	}
	data_source.Db.Where("id = ?", uid).Where("status = 1").Updates(upuser1)
	ctx.JSON(http.StatusOK, gin.H{
		"code":    0,
		"error":   0,
		"success": 200,
		"data":    "ok",
		"msg":     "ok",
	})
	return

}

func Loginxcx(ctx *gin.Context) {
	json1 := KDRespBody{}
	ctx.ShouldBind(&json1)
	click_id := json1.ClickId
	wxMap, err := sendWxAuthAPI(json1.Code)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "服务出错",
		})
		return
	}
	if _, ok := wxMap["errcode"]; ok {
		fmt.Println(wxMap["errmsg"])
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "请重新登录",
		})
		return
	}
	routine_openid := wxMap["openid"].(string)
	unionid := wxMap["unionid"].(string)
	session_key := wxMap["session_key"].(string)
	reqip := ctx.ClientIP()

	var uid int64
	var user models.User
	data_source.Db.Where("unionid = ?", unionid).Where("status = 1").First(&user)
	if user.ID > 0 {
		upuser1 := models.User{
			LoginIp:    reqip,
			LoginTime:  time.Now().Unix(),
			LoginNum:   user.LoginNum + 1,
			Newuser:    2,
			SessionKey: session_key,
		}
		data_source.Db.Where("id = ?", user.ID).Updates(upuser1)
		uid = user.ID
	} else {
		var user1 models.User
		data_source.Db.Where("routine_openid = ?", routine_openid).Where("status = 1").First(&user1)
		if user1.ID > 0 {
			upuser := models.User{
				LoginTime:  time.Now().Unix(),
				LoginIp:    reqip,
				LoginNum:   user.LoginNum + 1,
				Newuser:    2,
				SessionKey: session_key,
			}
			data_source.Db.Where("id = ?", user1.ID).Where("status = 1").Updates(upuser)
		} else {
			var laiyuan int64
			if click_id != "" {
				laiyuan = 2
			} else {
				laiyuan = 1
			}

			adduser := models.User{
				LoginTime:     time.Now().Unix(),
				LoginIp:       reqip,
				RoutineOpenid: routine_openid,
				CreateTime:    time.Now().Unix(),
				LoginNum:      1,
				Unionid:       unionid,
				Newuser:       1,
				SessionKey:    session_key,
				Logo:          "http://interstellar-tide-play.oss-cn-shanghai.aliyuncs.com/shequ/2024-10-08/1728354465logo.png",
				Nickname:      randomname.GenerateName(),
				Status:        1,
				Vip:           1,
				Qudao:         "weixin",
				ClickId:       click_id,
				Laiyuan:       laiyuan,
			}
			data_source.Db.Create(&adduser)
			uid = adduser.ID
			if click_id != "" {
				Zhuce(adduser)
			}

		}
	}

	var usernew models.User
	data_source.Db.Where("id = ?", uid).Where("status = 1").First(&usernew)
	ctx.JSON(http.StatusOK, gin.H{
		"code":    0,
		"error":   0,
		"success": 200,
		"data":    usernew,
		"msg":     "ok",
	})
	return

}

func Loginxcxshangbao(ctx *gin.Context) {
	json1 := KDRespBody{}
	ctx.ShouldBind(&json1)
	uid := json1.Uid
	var user models.User
	data_source.Db.Where("id = ?", uid).First(&user)
	data := Zhuce(user)
	ctx.JSON(http.StatusOK, gin.H{
		"code":    0,
		"error":   0,
		"success": 200,
		"data":    data,
		"msg":     "ok",
	})
	return

}
func Buycsshangbao(ctx *gin.Context) {
	json1 := KDRespBody{}
	ctx.ShouldBind(&json1)
	uid := json1.Uid
	var user models.User
	data_source.Db.Where("id = ?", uid).First(&user)
	data := Payshangbao(user, 982)
	ctx.JSON(http.StatusOK, gin.H{
		"code":    0,
		"error":   0,
		"success": 200,
		"data":    data,
		"msg":     "ok",
	})
	return

}

type Requesttoken struct {
	AccessToken string           `json:"access_token,omitempty"`
	User        Requesttokenuser `json:"user,omitempty"`
}
type Requesttokenuser struct {
	Uuid string `json:"uuid,omitempty"`
}

func generateRtmToken(memberid string) (token Requesttoken) {
	client := &http.Client{}
	song := make(map[string]interface{})
	song["grant_type"] = "inherit"
	song["username"] = memberid
	song["autoCreateUser"] = true
	bytesData, _ := json.Marshal(song)

	req, err := http.NewRequest("POST", "https://a1.easemob.com/1175240726208200/zhongyi/token",
		bytes.NewBuffer([]byte(bytesData)))
	if err != nil {
		fmt.Println("Fatal error ", err.Error())
	}

	//设置请求头
	req.Header.Set("content-type", "application/json")
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Authorization", "Bearer YWMt1CuB1kzTEe-PkWOk0cqVnqryEtLe2zf3ndBc8WJ9T5_RLkfeD81N8rJoAHGE1sotAgMAAAGQ-RToGAAAAADsIpYcwwme44_-_JnLGDmtRbOWx2XReeHKOvzczw1s9g")

	resp, err := client.Do(req)
	defer resp.Body.Close()

	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Fatal error ", err.Error())
	}
	r := Requesttoken{}
	//把请求到的结构反序列化到专门接受返回值的对象上面
	err = json.Unmarshal(content, &r)
	if err != nil {
		fmt.Println(err)
	}
	return r
}
func sendWxAuthAPI(code string) (map[string]interface{}, error) {
	var wxMap map[string]interface{}
	url := fmt.Sprintf(code2sessionURL, appID, appSecret, code)
	fmt.Println(url)
	resp, err := http.DefaultClient.Get(url)

	if err != nil {
		return wxMap, err
	}

	err = json.NewDecoder(resp.Body).Decode(&wxMap)
	if err != nil {
		return wxMap, err
	}
	defer resp.Body.Close()

	return wxMap, nil
}

// 手机号解密
type PhoneJmBody struct {
	EncryptedData string `json:"encryptedData" from:"encryptedData"`
	Iv            string `json:"iv" from:"iv"`
	Uid           int64  `json:"uid" from:"uid"`
}

func PhoneJm(ctx *gin.Context) {
	request := PhoneJmBody{}
	ctx.ShouldBind(&request)
	encryptedData := request.EncryptedData
	iv := request.Iv
	uid := request.Uid
	var user models.User
	data_source.Db.Where("id = ?", uid).First(&user)
	pc := wxbizdatacrypt.WxBizDataCrypt{AppId: appID, SessionKey: user.SessionKey}
	result1, err := pc.Decrypt(encryptedData, iv, false) //第三个参数解释： 需要返回 JSON 数据类型时 使用 true, 需要返回 map 数据类型时 使用 false
	//fmt.Println(result1)
	if err != nil {
		//fmt.Println(err)
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 0,
			"data":    err,
			"msg":     "no",
		})
		return
	} else {
		if resultMap, ok := result1.(map[string]interface{}); ok {
			//fmt.Println(resultMap)
			//fmt.Println(resultMap["phoneNumber"])
			phone := resultMap["phoneNumber"]
			var userphone models.User
			data_source.Db.Where("phone = ?", phone).Debug().Where("status = 1").First(&userphone)
			//fmt.Println(userphone)
			if userphone.ID > 0 {
				userupdate := models.User{
					LoginIp:       user.LoginIp,
					LoginTime:     time.Now().Unix(),
					LoginNum:      userphone.LoginNum + 1,
					Newuser:       2,
					SessionKey:    user.SessionKey,
					RoutineOpenid: user.RoutineOpenid,
					Unionid:       user.Unionid,
				}
				data_source.Db.Where("id = ?", userphone.ID).Updates(&userupdate)
				data_source.Db.Where("id = ?", uid).Delete(&models.User{})
				var userinfo models.User
				data_source.Db.Where("id = ?", userphone.ID).Where("status = 1").First(&userinfo)
				//fmt.Println(userinfo)
				ctx.JSON(http.StatusOK, gin.H{
					"code":    0,
					"error":   0,
					"success": 200,
					"data":    userinfo,
					"msg":     "ok",
				})
				return
			} else {
				data_source.Db.Model(&models.User{}).Where("id = ?", uid).Update("phone", phone.(string))
				user.Phone = phone.(string)
				ctx.JSON(http.StatusOK, gin.H{
					"code":    0,
					"error":   0,
					"success": 200,
					"data":    user,
					"msg":     "ok",
				})
				return
			}

		}

	}

}
